package com.loveyukari.service;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import com.loveyukari.dao.YubaPostDao;
import com.loveyukari.model.YubaPost;
import com.loveyukari.model.YubaPostComment;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import com.loveyukari.common.exception.InternalException;
import com.loveyukari.utils.HttpUtils;

import javax.annotation.PostConstruct;

/**
*
*yangshaohua
*2017年8月23日下午2:48:49
**/
@Service
public class YubaService {
	
	private static Logger log = LoggerFactory.getLogger(YubaService.class);

	@Autowired
	private YubaPostDao yubaPostDao;


	private static int tid = 564;
	private static String pageUrl = "https://yuba.douyu.com/wbapi/web/group/postlist";
	private static String postUrl = "https://yuba.douyu.com/wbapi/web/post/detail/";
	private static String commentUrl = "https://yuba.douyu.com/wbapi/web/post/comments/";

//	@Scheduled(cron = "20 * * * * *")
	public void yubaTask(){
		log.info("yuba task start");
		int page = 1;
		int total = -1;
		Map<String,Integer> postIdLikeMap = new HashMap<String,Integer>();
		Map<String,Integer> postIdCommentsMap = new HashMap<String,Integer>();
		Map<String,Date> postIdCreateTimeMap = new HashMap<String,Date>();

		Map<String,Integer> commentIdReplysMap = new HashMap<String,Integer>();
		Map<String,Integer> commentIdLikeMap = new HashMap<String,Integer>();
		Map<String,List<Integer>> postFloorsMap = new HashMap<String,List<Integer>>();


		HashMap<String, Object> pageParams = new HashMap<String, Object>();
		pageParams.put("group_id",tid);
		boolean pageWhileBreakFlag = false;
		while(true){
			try {
				if (page > total/30+1){
                    break;
                }
				pageParams.put("page",page++);
				JSONObject pageJson = JSONObject.fromObject(HttpUtils.sendGet(pageUrl, pageParams));
				total = pageJson.optInt("total", -1);
				JSONArray data = pageJson.optJSONArray("data");
				for (int i=0;i<data.size();i++){
                    try {
                        JSONObject dataJson = data.getJSONObject(i);
                        String postId = dataJson.optString("post_id");
                        int authId = dataJson.optInt("uid");
                        String nickname = dataJson.optString("nickname");
                        String title = dataJson.optString("title");
                        int comments = dataJson.optInt("comments");
                        YubaPost yubaPost = yubaPostDao.selectPostById(postId);
                        if (yubaPost == null){
                            yubaPost = new YubaPost();
                            yubaPost.setPostId(postId);
                            yubaPost.setAuthId(authId);
                            yubaPost.setTitle(title);
                            yubaPost.setNickname(nickname);
                        }
                        JSONObject postJson = JSONObject.fromObject(HttpUtils.sendGet(postUrl + postId)).optJSONObject("data");
                        String content = postJson.optString("content");
                        if (StringUtils.isEmpty(yubaPost.getContent())){
                            yubaPost.setContent(content);
                            yubaPost.setComments(comments);
                            yubaPostDao.insertPost(yubaPost);
                        } else if(comments != yubaPost.getComments()){
                            yubaPost.setComments(comments);
                            postIdCommentsMap.put(postId,comments);
                        }
                        String createAt = postJson.optString("created_at");
                        Date createTime = this.getDateByTimeShow(createAt);
                        if(yubaPost.getCreateTime() == null || yubaPost.getCreateTime().getTime() > createTime.getTime()){
                            yubaPost.setCreateTime(createTime);
                            postIdCreateTimeMap.put(postId,createTime);
                        }
                        int likes = postJson.optInt("likes");
                        if (likes != yubaPost.getLikes()){
                            yubaPost.setLikes(likes);
                            postIdLikeMap.put(postId,likes);
                        }
                        HashMap<String, Object> postParam = new HashMap<String, Object>();
                        postParam.put("group_id",tid);
                        int postPage = 1;
						int oldFloor = 0;
                        while(true){
                            try {
                                postParam.put("page",postPage++);
                                JSONObject commentResultJson = JSONObject.fromObject(HttpUtils.sendGet(commentUrl + postId, postParam));
                                JSONArray commentDatas = commentResultJson.optJSONArray("data");
                                for (int j=0;j<commentDatas.size();j++){
                                    try {
                                        JSONObject commentJson = commentDatas.getJSONObject(j);
                                        String commentId = commentJson.optString("comment_id_str");
                                        int floor = commentJson.optInt("floor");
                                        for(int ii=oldFloor+1;ii<floor;ii++){
											List<Integer> list = postFloorsMap.get(postId);
											if (list == null){
												list = new ArrayList<Integer>();
												postFloorsMap.put(postId,list);
											}
											list.add(ii);
                                        }
                                        oldFloor = floor;
                                        long commentCreatedTs = commentJson.optLong("created_ts");

                                        Date commentCreateTime = new Date(commentCreatedTs*1000);
                                        if (j == 0 && yubaPost.getCreateTime().getTime() > commentCreateTime.getTime()){
                                            yubaPost.setCreateTime(commentCreateTime);
                                            postIdCreateTimeMap.put(postId,createTime);
                                        }
                                        YubaPostComment postComment = yubaPostDao.selectCommentByCommentId(commentId);
                                        if (postComment == null){
                                            postComment = new YubaPostComment();
                                            postComment.setCommentId(commentId);
											postComment.setPostId(postId);
                                            postComment.setAuthId(commentJson.optInt("uid"));
                                            postComment.setNickname(commentJson.optString("nick_name"));
                                            postComment.setContent(commentJson.optString("raw_content"));
                                            postComment.setFloor(floor);
                                            postComment.setCreateTime(commentCreateTime);
                                            yubaPostDao.insertPostcomment(postComment);
                                        }
                                        int commentLikes = commentJson.optInt("likes");
                                        if (postComment.getLikes() != commentLikes){
                                            postComment.setLikes(commentLikes);
                                            commentIdLikeMap.put(commentId,commentLikes);
                                        }
                                        JSONArray replies = commentJson.optJSONArray("sub_replies");
                                        if (postComment.getReplys() != replies.size()){
                                            postComment.setReplys(replies.size());
                                            commentIdReplysMap.put(commentId,replies.size());
                                        }
                                        for(int jj=0;jj<replies.size();jj++){
                                            try {
                                                JSONObject reply = replies.getJSONObject(jj);
                                                String replyId = reply.optString("comment_reply_id_str");
                                                YubaPostComment replyPostComment = yubaPostDao.selectCommentByCommentId(replyId);
                                                if (replyPostComment == null){
                                                    replyPostComment = new YubaPostComment();
                                                    replyPostComment.setCommentId(replyId);
                                                    replyPostComment.setFloor(floor);
                                                    replyPostComment.setContent(reply.getString("content"));
                                                    replyPostComment.setNickname(reply.getString("nickname"));
                                                    replyPostComment.setAuthId(reply.getInt("uid"));
                                                    replyPostComment.setParentCommentId(commentId);
                                                    replyPostComment.setPostId(postId);
                                                    replyPostComment.setCreateTime(new Date(reply.optLong("created_ts")*1000));
                                                    yubaPostDao.insertPostcomment(replyPostComment);
                                                }
                                                int replyLikes = reply.optInt("likes");
                                                if (replyLikes != replyPostComment.getLikes()){
                                                    commentIdLikeMap.put(replyId,replyLikes);
                                                }
                                            } catch (Exception e) {
                                                log.error(e.getMessage(),e);
                                            }
                                        }
                                    } catch (Exception e) {
                                        log.error(e.getMessage(),e);
                                    }

                                }
                                if (commentResultJson.optInt("page") >= commentResultJson.optInt("page_total")){
                                    break;
                                }
                            } catch (Exception e) {
                                log.error(e.getMessage(),e);
                            }
                        }
                        if (dataJson.optInt("user_set_top") == 0){
							String lastReplyTimeStr = dataJson.optString("last_reply_time");
							Date lastReplyTime = this.getDateByTimeShow(lastReplyTimeStr);
							if (System.currentTimeMillis() - lastReplyTime.getTime() > 900000){
								pageWhileBreakFlag = true;
								break;
							}
						}

                    } catch (Exception e) {
                        log.error(e.getMessage(),e);
                    }
                }
                if(pageWhileBreakFlag){
					break;
				}
			} catch (Exception e) {
				log.error(e.getMessage(),e);
			}
		}
		yubaPostDao.updatePostLike(postIdLikeMap);
		yubaPostDao.updatePostComments(postIdCommentsMap);
		yubaPostDao.updatePostCreateTime(postIdCreateTimeMap);
		yubaPostDao.updatePostCommentReplys(commentIdReplysMap);
		yubaPostDao.updatePostCommentLike(commentIdLikeMap);
		yubaPostDao.updatePostCommentStatusByPostFloor(postFloorsMap,-1);
		log.info("yuba task end");
	}

	private SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy");
	private SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy-MM-dd");
	private SimpleDateFormat sdfMinutes = new SimpleDateFormat("yyyy-MM-dd HH:ss");
	private Date getDateByTimeShow(String timeShow) throws ParseException {
		if(StringUtils.isEmpty(timeShow)){
			return null;
		} else if(StringUtils.equals("刚刚",timeShow)){
			return new Date();
		} else if(timeShow.matches("^([1-6]\\d|\\d)分钟前$")){
			int minutes = Integer.parseInt(timeShow.substring(0,timeShow.length()-3));
			return DateUtils.addMinutes(new Date(),-minutes);
		} else if (timeShow.matches("^[1-4]小时前$")){
			int hours = Integer.parseInt(timeShow.substring(0,timeShow.length()-3));
			return DateUtils.addHours(new Date(),-hours);
		} else if (timeShow.matches("^([01]\\d|2[01234]):([0-5]\\d)$")){
			return sdfMinutes.parse(sdfDay.format(new Date())+" "+timeShow);
		} else if (timeShow.matches("^昨天([01]\\d|2[01234]):([0-5]\\d)$")){
			return sdfMinutes.parse(sdfDay.format(DateUtils.addDays(new Date(),-1))+" "+timeShow.replace("昨天",""));
		} else if (timeShow.matches("^(0[1-9]|1[012])-([0-2]\\d|3[01])$")){
			return sdfDay.parse(sdfYear.format(new Date())+"-"+timeShow);
		} else if (timeShow.matches("^(19[789]\\d|20\\d\\d)-(0[1-9]|1[012])-([0-2]\\d|3[01])$")){
			return sdfDay.parse(timeShow);
		}
		return null;
	}

	public static void main(String[] args) {
		String s = "昨天12:41";
		System.out.println(s.matches("昨天([01]\\d|2[01234]):([0-5]\\d)$"));
	}


	
}
